from __future__ import with_statement 
import sys
import os
from mod_python import apache
from mod_python import Session
from mod_python import psp
from mod_python import util
import json 

HWCHECKER_HEADER_ERRCODE = 'X-HWChecker-ErrorCode'
HWCHECKER_HEADER_ERRMSG  = 'X-HWChecker-ErrorMsg'

E_NO_ERROR = 0
E_NOT_AUTH = 1
E_INVALID_AUTH = 2
E_INVALID_REQ = 3

AUTH_LEVEL_STUDENT = 1
AUTH_LEVEL_ASSISTANT = 2

AUTH_DB = [{'username' : 'test', 
           'password' : 'pass',
           'type' : AUTH_LEVEL_STUDENT
           },
           {'username' : 'asistent', 
            'password' : 'pass',
            'type' : AUTH_LEVEL_ASSISTANT
            }
           ]

HW1 = { 'id':'1', 'shortname':'Tema 1', 'longname':'Mini shell', 'description':'blah'}
HW2 = { 'id':'2', 'shortname':'Tema 2', 'longname':'Memorie partajata', 'description':'um...'}   

HW_CONFIG = [HW1, HW2]

def TEST_auth(credentials):
    for user in AUTH_DB:
        if (user['username'] == credentials['username']) and (user['password'] == credentials['password']):
            return user
    return None

def __dump_headers(headers, filename):
    with open(filename, 'w') as f:
        for key in headers.keys():            
            f.write(key + ": " + str(headers[key]) + "\n")    

def set_response(req, error, msg = ''):
    req.headers_out[HWCHECKER_HEADER_ERRCODE] = str(error)
    req.headers_out[HWCHECKER_HEADER_ERRMSG] = msg

def auth_req(session):
    """ Checks for previously authentication """
    if session.is_new():
        return False
    else:
        return True

def perform_auth(session, credentials):
    user_entry = TEST_auth(credentials)
    if user_entry != None:
        session['authLevel'] = user_entry['type']
        session['userName'] = credentials['username']
        session.save()
        return True
    else:
        return False

def display_page(req, filename, params):
    req.content_type = 'text/html'
    template = psp.PSP(req, filename)
    template.run(params)

# Web Page Requests
################################################################################

def index(req):
    session = Session.Session(req)
    
    __dump_headers(req.headers_in, "/tmp/headers_in.txt")
    __dump_headers(req.headers_out, "/tmp/headers_out.txt")
    if not auth_req(session):
        util.redirect(req, 'login')
    else:
        util.redirect(req, 'app')
    

def login(req):
    session = Session.Session(req)
    
    if not auth_req(session):
        display_page(req, 'html/login.html', {})
    else:
        util.redirect(req, 'app');
    
def app(req):
    session = Session.Session(req)
    
    if not auth_req(session):
        util.redirect(req, 'login')
    else:
        display_page(req, 'html/checker.html', {'authLevel' : session['authLevel'], 'userName' : session['userName']})
        
def logout(req):
    session = Session.Session(req)
    session.invalidate()
    util.redirect(req, 'login')

# Data requests
################################################################################

def auth(req, username = 'None', password = 'None'):
    session = Session.Session(req)
    if not auth_req(session):
        auth_result = perform_auth(session, {'username' : username, 'password' : password})
        if auth_result == False:
            session.invalidate()
            set_response(req, E_NOT_AUTH, "Wrong username or password")
        else:
            set_response(req, E_NO_ERROR, "Authentication succeeded")
    else:
        set_response(req, E_NO_ERROR, "Already authenticated")

    __dump_headers(req.headers_in, "/tmp/headers_in.txt")
    __dump_headers(req.headers_out, "/tmp/headers_out.txt")
    
def homework(req):
    # TODO: This method is a stub. Please fill it accordingly
    session = Session.Session(req)
    if not auth_req(session):
        session.invalidate()
        set_response(req, E_NOT_AUTH, "Request not authenticated")
        return 

    set_response(req, E_NO_ERROR)
    req.content_type = 'text/plain' 
    response = HW_CONFIG    
    req.write(json.write(response))
